home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
toolfix.arc
/
BIGTRE.BOX
next >
Wrap
Text File
|
1987-03-03
|
13KB
|
404 lines
(*******************************************)
(* *)
(* BIGTREE.BOX *)
(* (for PC-DOS and MS-DOS systems) *)
(* *)
(* by *)
(* Bruce A. Butters *)
(* *)
(* updated January 4, 1986 *)
(* *)
(*******************************************)
The following changes to Turbo DataBase ToolBox code will permit your database
programs to access more than 65,536 records (DOS only). With a three-byte
integer replacing the standard integer as record numbers and page numbers, the
maximum number of records in the BIGTREE system becomes 16,777,214. Note
that the minimum record size increases to 16 as a result. I have added
code to default to the correct file size if the record length<16.
NOTE: With the increased capacity of BIGTREE, it is possible to specify
a tree structure that is inadequate to handle the maximum number of
records. The maximum tree capacity is a function of PageSize and MaxHeight
(and, of course, Order). For instance, with MaxHeight=5 you should set
PageSize to at least 52 to accomodate 16M records.
I have not tested these changes thoroughly. Use at your own risk.
If you use BIGTREE, successfully or otherwise, I'd appreciate it if you'd
let me know how it works for you. Leave a message in the forum for
Bruce Butters [76317,2433].
Good Luck!
CHANGES TO ACCESS3.BOX:
----------------------
1. add a constant declaration: const MinDataRecLen=16;
Changes to type declarations:
2. The first type declaration should be LongInt = string[3];
3. Change the DataFile type to
DataFile = record
case Integer of
0 : (F : file;
FirstFree,
NumberFree,
Int1,
Int2,
NumRec : LongInt);
1 : (Fil2 : array[1..12] of Byte;
TaName : array[1..64] of Char);
end;
4. With TaItem change type of DataRef and PageRef to LongInt.
5. With TaPage change type of BckwPageRef to LongInt.
6. With TaSearchStep change type of PageRef to LongInt.
7. With IndexFile change type of RR (only) to LongInt.
8. With TaStackRec change type of PageRef to LongInt.
9. With TaRecordBuffer change type of I to LongInt.
Changes to functions & procedures:
10. add the following functions as the first functions in the code:
(If you can come up with more elegant code than these
two kludges, please feel free to share them)
FUNCTION Long(R : real) : LongInt;
var
n : real;
i : integer;
begin
R := abs(R);
i := trunc(R/65536.0);
Long[1] := chr(i);
n := (R-(i*65536.0));
if n<32768.0 then i := trunc(n)
else if n>32768.0 then i := trunc(n-65536.0)
else i := $8000; {Turbo won't accept -32768}
Long[3] := chr(lo(i));
Long[2] := chr(hi(i));
Long[0] := chr(3);
end; {Long}
FUNCTION LongVal(I : LongInt) : real;
var
R : real;
n : integer;
begin
R := ord(I[1])*65536.0;
n := ord(I[2])*256+ord(I[3]);
if n<0 then R := R+65536.0+n else R := R+n;
LongVal := R;
end; {LongVal}
11. In TaIOCheck change parameter type R to real and change
writeln(' Record ',R) to writeln(' Record ',R:0:0);
12. In GetRec change the type of parameter R to real. Change
Seek(DatF.F,R); to LongSeek(DatF.F,R);
13. In PutRec change the type of parameter R to real. Change
Seek(DatF.F,R) to LongSeek(DatF.F,R);
14. In MakeFile add a var R : Integer; to the procedure.
After the first call to TaIOCheck add
if RecLen<MinDataRecLen then R := MinDataRecLen else R := RecLen;
then change Rewrite(DatF.F,RecLen) to Rewrite(DatF.F,R);
Change the record zero initialization to
else
begin
TaIOCheck(DatF,0);
DatF.FirstFree := Long(0);
DatF.NumberFree := Long(0);
DatF.Int1 := Long(0);
DatF.Int2 := Long(0);
Move(DatF.FirstFree,TaRecBuf,16);
PutRec(DatF,0,TaRecBuf);
DatF.NumRec := Long(1.0);
OK := true;
end;
15. In OpenFile add a var R : Integer; to the procedure.
After the first call to TaIOCheck add
if RecLen<MinDataRecLen then R := MinDataRecLen else R := RecLen;
Then: Reset(DatF.F,R);
Change the number of bytes in the Move procedure from 8 to 16.
Then: DatF.NumRec := Long(LongFileSize(DatF.F));
16. In CloseFile change the number of bytes in the Move procedure from
8 to 16.
17. In NewRec change the parameter R to type real.
Then:
if LongVal(DatF.FirstFree) < 1.0 then
begin
R := LongVal(DatF.NumRec);
DatF.NumRec := Long(R + 1.0);
end
else
begin
R := LongVal(DatF.FirstFree);
GetRec(DatF,R,TaRecBuf);
DatF.FirstFree := TaRecBuf.I;
DatF.NumberFree := Long(LongVal(DatF.NumberFree) - 1.0);
end;
18. In AddRec change parameter R to type real.
19. In DeleteRec change parameter R to real. After the PutRec
statement, then:
DatF.FirstFree := Long(R);
DatF.NumberFree := Long(LongVal(DatF.NumberFree) + 1.0);
20. Change the result type of FileLen to real. The function
statement then is: FileLen := LongVal(DatF.NumRec);
21. Change the result type of UsedRecs to real. The function
statement then is:
UsedRecs := LongVal(DatF.NumRec) - LongVal(DatF.NumberFree) - 1.0;
22. Change the Move procedure in TaPack to:
Move(Page.ItemArray[I],P[(I - 1) * (KeyL + 9) + 5],KeyL + 9);
23. Change the Move procedure in TaUnpack to:
Move(P[(I - 1) * (KeyL + 9) + 5],Page.ItemArray[I],KeyL + 9);
24. Change the first statement in MakeIndex to:
K := (KeyLen + 9)*PageSize + 5;
then change IdxF.RR := 0; to IdxF.RR := Long(0);
25. Change the first statement of OpenIndex to:
K := (KeyLen + 9) * PageSize + 5;
26. In CloseIndex, change the PutRec statement to:
PutRec(IdxF.DataF,LongVal(PageRef),Page);
27. Change the parameter R in TaGetPage to type real.
The assignment to Boolean Found should read:
Found := (IndexFPtr = Addr(IdxF)) and (LongVal(PageRef) = R);
Change the call to PutRec to:
PutRec(IndexFPtr^.DataF,LongVal(PageRef),Page);
Then the assignment to PageRef to: PageRef := Long(R);
28. Change the parameter R in TaNewPage to type real.
Change the call to PutRec to:
PutRec(IndexFPtr^.DataF,LongVal(PageRef),Page);
Then the assignment to PageRef should be: PageRef := Long(R);
29. In TaReturnPage change the call to DeleteRec to:
DeleteRec(IndexFPtr^.DataF,LongVal(PageRef));
30. In TaCompKeys change the parameter type of DR1 and DR2 to real.
Then, change
if Dup then
TaCompKeys := DR1 - DR2
else TaCompKeys := 0
to:
if Dup then
begin
if DR1>DR2 then TaCompKeys:=1 else
if DR1<DR2 then TaCompKeys:=-1
end
else TaCompKeys := 0;
CHANGES TO GETKEY.BOX:
---------------------
1. In NextKey, change the parameter ProcDataRef type to real. Also,
change the variable R to type real.
Change line 5 ('begin' = line 1) to: R := LongVal(RR)
Change lines 9 and 10 to:
TaGetPage(IdxF,LongVal(PageRef),PagPtr);
R := LongVal(PagPtr^.ItemArray[ItemArrIndex].PageRef);
Change line 17 to: PageRef := Long(R);
Line 21 to: R := LongVal(PagPtr^.BckwPageRef);
Line 29 to: TaGetPage(IdxF,LongVal(Path[PP].PageRef),PagPtr);
Line 38 to: ProcDatRef := LongVal(DataRef);
2. In PrevKey, change parameter ProcDataRef to type real. Also,
change the variable R to type real.
Change line 5 to: R := LongVal(RR)
Change line 9 to: TaGetPage(IdxF,LongVal(PageRef),PagPtr);
Change lines 12 & 13 to:
R := LongVal(PagPtr^.BckwPageRef)
else R := LongVal(PagPtr^.ItemArray[ItemArrIndex].PageRef);
Line 21 to: PageRef := Long(R);
Line 25 to: R := LongVal(ItemArray[ItemsOnPage].PageRef);
Line 32 to: TaGetPage(IdxF,LongVal(Path[PP].PageRef),PagPtr);
Line 38 to: ProcDatRef := LongVal(DataRef);
3. In TaFindKey change parameter ProcDataRef to type real. Also,
change variable PrPgRef to type real.
Line 7 to: PrPgRef := LongVal(RR);
Line 11 to: Path[PP].PageRef := Long(PrPgRef);
Change lines 19 through 23 to:
C := TaCompKeys(PKey,
ItemArray[K].Key,
0,
LongVal(ItemArray[K].DataRef),
AllowDuplKeys );
Line 31 to: ProcDatRef := LongVal(ItemArray[K].DataRef);
Lines 36 & 37 to:
PrPgRef := LongVal(BckwPageRef)
else PrPgRef := LongVal(ItemArray[R].PageRef);
4. In FindKey, change the parameter ProcDataRef to type real.
5. In SearchKey, change the parameter ProcDataRef to type real.
CHANGES TO ADDKEY.BOX
---------------------
1. In AddKey, change the parameter ProcDataRef to type real.
Change the variables PrPgRef1, PrPgRef2 to type real and
add a variable Temp : real.
2. In Search, change the parameter PrPageRef1 to type real.
3. In Insert, 7 lines from the last 'end' (of Insert) change to:
ProcItem2.PageRef := Long(PrPgRef2);
4. In the body of Search ('begin' = line 1) change lines
8 & 9 to:
DataRef := Long(ProcDatRef);
PageRef := Long(0);
Change lines 21-25 to:
C := TaCompKeys(PKey,
ItemArray[K].Key,
ProcDatRef,
LongVal(ItemArray[K].DataRef),
IdxF.AllowDuplKeys );
Change lines 38-40 to:
if R = 0 then
Search(LongVal(BckwPageRef))
else Search(LongVal(ItemArray[R].PageRef));
5. In the body of AddKey, change line 6 to: Search(LongVal(RR));
Starting with line 8, change to:
begin
PrPgRef1:=LongVal(RR);
Temp:=PrPgRef;
TaNewPage(IdxF,Temp,PagePtr1);
if Temp<>LongVal(RR) then RR:=Long(Temp);
with PagePtr1^ do
begin
ItemsOnPage:=1;
BckwPageRef:=Long(PrPgRef1);
{then continue as in original code}
CHANGES TO DELKEY.BOX
---------------------
1. In DeleteKey, change the parameter ProcDataRef to type real.
2. In DelB, change the parameter PrPgRef to type real. Change the
variable XPageRef to type real.
3. In UnderFlow, change the parameters PrPgRef1 & PrPgRef2 to type
real. Change variable LPageRef to type real.
Change line 7 to: LPageRef := LongVal(PagPtr^.ItemArray[R].PageRef);
Line 17 to: PagPtr^.ItemArray[R].PageRef := Long(LPageRef);
Lines 41-43 to:
if R = 1 then
LPageRef := LongVal(PagPtr^.BckwPageRef)
else LPageRef := LongVal(PagPtr^.ItemArray[R - 1].PageRef);
Line 58 to: PagPtr^.ItemArray[R].PageRef := Long(PrPgRef2);
4. In DelA, change the parameter PrPgRef2 to type real.
Change the variable XPageRef to type real.
Change line 5 to: XPageRef := LongVal(ItemArray[ItemsOnPage].PageRef);
5. In the body of DelB, change lines 16-20 ('begin' = line 1) to:
C := TaCompKeys(PKey,
ItemArray[K].Key,
ProcDatRef,
LongVal(ItemArray[K].DataRef),
IdxF.AllowDuplKeys );
Lines 26-28 to:
if R = 0 then
XPageRef := LongVal(BckwPageRef)
else XPageRef := LongVal(ItemArray[R].PageRef);
Line 31 to: ProcDatRef := LongVal(ItemArray[K].DataRef);
6. In the body of DeleteKey, change line 6 to:
DelB(LongVal(RR));
Change line 9 to: TaGetPage(IdxF,LongVal(RR),PagPtr);
THAT'S ALL!!!